package com.yushu.authority.service.impl;

import com.baomidou.mybatisplus.enums.SqlLike;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.toolkit.IdWorker;
import com.yushu.authority.mapper.PmUserMapper;
import com.yushu.authority.pojo.bo.PmOrg;
import com.yushu.authority.pojo.bo.PmUser;
import com.yushu.authority.pojo.vo.PmUserVO;
import com.yushu.authority.service.PmMenuService;
import com.yushu.authority.service.PmOrgService;
import com.yushu.authority.service.PmRoleService;
import com.yushu.authority.service.PmUserService;
import com.yushu.common.execption.CgException;
import com.yushu.common.shiro.ShiroUtil;
import com.yushu.common.util.date.DateUtils;
import com.yushu.common.util.pager.Pages;
import com.yushu.common.util.string.CamelCaseUtil;
import com.yushu.common.util.string.UUIDUtils;
import com.yushu.common.service.impl.YSBaseServiceImpl;
import com.yushu.authority.pojo.bo.PmRole;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.*;
import java.util.concurrent.TimeUnit;


/**
 * 
 * @author test
 * @CreateDate 2020-12-03 15:47:25
 */
@Service("pmUserService")
public class PmUserServiceImpl extends YSBaseServiceImpl<PmUserMapper, PmUser> implements PmUserService {
    @Autowired
    private PmRoleService roleService;
    @Autowired
    private PmUserService userService;
    @Autowired
    private PmOrgService orgService;
    @Autowired
    private RedisTemplate redisTemplate;
 	@Autowired
    private PmMenuService pmMenuService;

	@Autowired
    JavaMailSender javaMailSender;

    //发送者
   
    @Value("${spring.mail.username}")
    private String form;

    @Autowired
    HttpServletRequest request;

    @Override
    public Pages<PmUserVO> page(Pages<PmUserVO> page) {
        PmUser sessionUser = ShiroUtil.getSessionUser();
        EntityWrapper wrapper = new EntityWrapper<PmUserVO>();
        PmUserVO userCache = (PmUserVO) redisTemplate.opsForValue().get("userSession_" + sessionUser.getId());

        PmUserVO pmUser = page.getData();
        if (null != pmUser) {
            if (StringUtils.isNotEmpty(pmUser.getOrgId())) {
                wrapper.like("t.org_id", pmUser.getOrgId(), SqlLike.DEFAULT);
            }
            if (StringUtils.isNotEmpty(pmUser.getUserName())) {
                wrapper.like("t.user_name", pmUser.getUserName(), SqlLike.DEFAULT);
            }
            if (StringUtils.isNotEmpty(pmUser.getUserState())) {
                wrapper.like("t.user_state", pmUser.getUserState(), SqlLike.DEFAULT);
            }
            if (StringUtils.isNotEmpty(pmUser.getUserType())) {
                wrapper.like("t.user_type", pmUser.getUserType(), SqlLike.DEFAULT);
            }
            if (null != pmUser.getCreateTimeBefore() && null != pmUser.getCreateTimeAfter()) {
                String dateBefore = DateUtils.dateToString(pmUser.getCreateTimeBefore());
                String dateAfter = DateUtils.dateToString(pmUser.getCreateTimeAfter());
                wrapper.between("t.create_time", dateBefore, dateAfter);
            }
            if (null != pmUser.getUpdateTimeBefore() && null != pmUser.getUpdateTimeAfter()) {
                String dateBefore = DateUtils.dateToString(pmUser.getUpdateTimeBefore());
                String dateAfter = DateUtils.dateToString(pmUser.getUpdateTimeAfter());
                wrapper.between("t.update_time", dateBefore, dateAfter);
            }
            if (null != pmUser.getBirthdayBefore() && null != pmUser.getBirthdayAfter()) {
                String dateBefore = DateUtils.dateToString(pmUser.getBirthdayBefore());
                String dateAfter = DateUtils.dateToString(pmUser.getBirthdayAfter());
                wrapper.between("t.birthday", dateBefore, dateAfter);
            }
            if (StringUtils.isNotEmpty(pmUser.getUserSex())) {
                wrapper.like("t.user_sex", pmUser.getUserSex(), SqlLike.DEFAULT);
            }
            if (StringUtils.isNotEmpty(pmUser.getUserPortrait())) {
                wrapper.like("t.user_portrait", pmUser.getUserPortrait(), SqlLike.DEFAULT);
            }
            if (StringUtils.isNotEmpty(pmUser.getUserEmail())) {
                wrapper.like("t.user_email", pmUser.getUserEmail(), SqlLike.DEFAULT);
            }
            if (StringUtils.isNotEmpty(pmUser.getUserWeixin())) {
                wrapper.like("t.user_weixin", pmUser.getUserWeixin(), SqlLike.DEFAULT);
            }
            if (StringUtils.isNotEmpty(pmUser.getUserQq())) {
                wrapper.like("t.user_qq", pmUser.getUserQq(), SqlLike.DEFAULT);
            }
            if (StringUtils.isNotEmpty(pmUser.getUserTel())) {
                wrapper.like("t.user_tel", pmUser.getUserTel(), SqlLike.DEFAULT);
            }
            if (StringUtils.isNotEmpty(page.getSort())) {
                wrapper.orderBy(CamelCaseUtil.toUnderlineName(page.getSort()), "asc".equals(page.getOrder()));
            }
        }
        List<PmUserVO> list = baseMapper.selectPageList(page, wrapper);
        page.setRecords(list);
        return page;
    }


    /**
     * 批量删除用户
     *
     * @param pmUsers
     * @return
     */
    public boolean deleteBatch(List<PmUser> pmUsers) throws CgException {
        boolean deleteState = false;
        try {
            if (CollectionUtils.isNotEmpty(pmUsers)) {
                int countRolesOnuser = userService.queryRoleCountOnUsers(pmUsers);
                if(countRolesOnuser>0){
                    throw new CgException("当前用户下有角色，不允许删除");
                }
                List<String> ids = new ArrayList<String>();
                for (int i = 0; i < pmUsers.size(); i++) {
                    PmUser pmUser = pmUsers.get(i);
                    ids.add(pmUser.getId());
                }
                deleteState = deleteBatchIds(ids);
            }

        } catch (Exception e) {
            e.printStackTrace();
            throw new CgException(e.getMessage());
        }
        return deleteState;
    }


    /**
     * 通过主键更新用户的缓存数据
     *
     * @param pmUser
     * @return
     */
    //@CachePut(value = "pmUser", key = "#pmUser.id")
    public PmUser updateByKey(PmUser pmUser) throws CgException {
        try {
            PmUser sessionUser = ShiroUtil.getSessionUser();
            pmUser.setUpdateTime(new Date());
            super.updateById(pmUser);
        } catch (RuntimeException e) {
            throw new CgException(e.getMessage());
        }
        return pmUser;
    }


    /**
     * 保存的时候清除所有用户的缓存数据
     *
     * @param user
     * @return
     */
    /**
     * <pre>
     *      用户注册
     * </pre>
     * TODO 2019-11-08 10:32:37 待完成任务 1、保存用户，保存用户角色相关数据
     *
     * @param user
     * @return boolean
     * @author test
     * @since 2019/11/7  13:08
     **/
    @Override
    public boolean insert(PmUser user) throws CgException {
        try {


            PmUser sessionUser = ShiroUtil.getSessionUser();
            if (null != sessionUser) {
                PmUserVO userCache = (PmUserVO) redisTemplate.opsForValue().get("userSession_" + sessionUser.getId());
                user.setOrgId(sessionUser.getOrgId());
            }

            user.setCreateTime(new Date());
            if (StringUtils.isEmpty(user.getPassword())) {
                SimpleHash sh = new SimpleHash("MD5", "123456", user.getUserName(), 1);
                user.setPassword(sh.toString());
            }

            user.setCreateTime(new Date());
            user.setId(IdWorker.get32UUID());
            baseMapper.insert(user);
            return true;
        } catch (RuntimeException e) {
            e.printStackTrace();
            throw new CgException(e.getMessage());
        }
    }

    /**
     * 用户注册
     *
     * @param user
     */
    @Override
    public boolean register(PmUser user) {
//        FIXME 2019-12-31 15:03:07 功能待修复

            /*
                1、保存用户
                2、保存用户相关的角色
                3、
                全局角色类型应该分为三种，个人角色类用户，客户角色类用户，酷钉类角色用户
             */

        if (null != user.getPassword()) {
            SimpleHash sh = new SimpleHash("MD5", user.getPassword(), user.getUserName(), 1);
            user.setPassword(sh.toString());
        } else {
            throw new CgException("用户密码不能为空");
        }

        userService.insert(user);
        //TODO 2020-4-2 17:33:12 保存用户的角色（和代码生成器相关，需要注意）
      
//        TODO ，用户注册之后同时保存用户相关的权限，和机构内容
//        roleService.saverUserAndRole(user);
        PmOrg pmOrg = new PmOrg();
        pmOrg.setOrgName("个人机构");
        pmOrg.setCreateTime(new Date());
        pmOrg.setPid("-1");
        pmOrg.setOrgIntro("个人机构");
        pmOrg.setOrgLeader(user.getUserName());
        pmOrg.setId(UUIDUtils.getUUID32());

        Map map = new LinkedHashMap();
        map.put("id",UUIDUtils.getUUID32());
        map.put("userId",user.getId());
        map.put("roleId","82d968a756e34ff285a9c1260f7b4b3e");

        baseMapper.insertUserAndRole(map);

        return orgService.insert(pmOrg);
    }

    @Override
    public int queryRoleCountOnUsers(List<PmUser> pmUsers) {
        if (CollectionUtils.isNotEmpty(pmUsers)) {
            return baseMapper.queryRoleCountOnUsers(pmUsers);
        } else {
            return 0;
        }
    }

	// 查询邮箱是否存在
    @Override
    public Map<String ,Object> queryEmail(String userEmail) {
    
     Map<String, Object> map = new HashMap<>();
 
        //生成随机验证码
        String code = "";
        for(int i = 0 ;i<4;i++){
            code+=(int)Math.floor(Math.random()*10);
        }
        //判断该邮箱是否存在
        int pmUser = baseMapper.queryEmail(userEmail);
        if (pmUser != 0) {
            //建立邮件消息
            SimpleMailMessage mailMessage = new SimpleMailMessage();
            //发送者
            mailMessage.setFrom(form);
            //接收者
            mailMessage.setTo(userEmail);
            //发送的标题
            mailMessage.setSubject("密码验证");
            //发送的内容
            mailMessage.setText(code);
            javaMailSender.send(mailMessage);
            //发送成功后保存在redis
            BoundValueOperations<String,Object> codes = redisTemplate.boundValueOps("codes");
            //设置验证码的失效时间
            redisTemplate.opsForValue().set("codes",code,3000, TimeUnit.SECONDS);
           	map.put("count","1");
        } else {
           map.put("count","0");
        }
        //获取保存在redis里面的验证码
        String code1 = (String) redisTemplate.opsForValue().get("codes");
        	map.put("code",code1);
        	map.put("code",code);
        	return map;

    }

    //修改密码
    @Override
    public int changePassword(PmUserVO pmUserVO) {
        return baseMapper.changePassword(pmUserVO);
    }
   

	 //验证旧密码是否正确
    @Override
    public PmUser queryoldPassword(String oldPassword, String key) {
        //System.out.println(oldPassword + "," + key);

        PmUser pmUser = new PmUser();
        pmUser.setUserName(key);
        PmUser pmUser1 = baseMapper.validateUserName(pmUser);
        SimpleHash sh = new SimpleHash("MD5", oldPassword, pmUser.getUserName(), 1);
        PmUser pmUserValue = baseMapper.queryoldPassword(sh.toString(), key);
        return pmUser1;
    }

    @Override
    public PmUser wUserEmail(String userEmail) {
        return baseMapper.wUserEmail(userEmail);
    }

     //修改忘记密码
    @Override
    public boolean changeForgetPassword(PmUserVO pmUserVO) {
        return baseMapper.changeForgetPassword(pmUserVO);
    }

   	@Override
    public PmUser validateUserName2(PmUser pmUser) {
        return baseMapper.validateUserName(pmUser);
    }

    
    /**
     * 查询时保存用户的缓存数据
     *
     * @param id 主键
     * @return
     */
    //@Cacheable(value = "pmUser", key = "#id")
    @Override
    public PmUser selectById(Serializable id) {
        return super.selectById(id);
    }


    @Override
    public PmUserVO queryPmUserByKey(String id) {
        return baseMapper.queryPmUserByKey(id);
    }

    @Override
    public String checkRepeat(Map map) {
        String name = map.get("name") + "";//字段名
        String value = map.get("value") + "";//name
        String key = map.get("key") + "";//id

        /*通过姓名查询是否存在*/
        int count = baseMapper.queryCountByName(map);
        /*if(StringUtils.isBlank(key)&&count==0){

        }*/
        //如果key存在，则是修改，否则是新增
        if (StringUtils.isNotBlank(key)) {
            /*如果是更新，则数字可以大于1*/
            if (count <= 0) {
                return "true";
            } else if (count > 1) {//说明存在多个
                return "false";
            } else if (count == 1) {

                EntityWrapper wrapper = new EntityWrapper<PmUser>();
                wrapper.eq(name, value);
                List<PmUser> pmUsers = baseMapper.selectList(wrapper);
                String checkExit = "true";
                if (CollectionUtils.isNotEmpty(pmUsers)) {
                    for (int i = 0; i < pmUsers.size(); i++) {
                        PmUser pmUser = pmUsers.get(i);
//                        说明当前值象存在于不同的对象之中，也不能重复
                        if (!StringUtils.equals(pmUser.getId().trim(), key.trim())) {
                            checkExit = "false";
                        }
                    }
                }
                return checkExit;
            } else {
                return "true";
            }
        } else {
            /*如果是新增，则数字可以大于0*/
            if (count > 0) {
                return "false";
            } else {
                return "true";
            }
        }
    }

    @Override
    public List<PmUser> selectList(PmUser pmUser) {
        EntityWrapper wrapper = new EntityWrapper<PmUser>();
        if (StringUtils.isNotEmpty(pmUser.getId())) {
            wrapper.eq("id", pmUser.getId());
        }
        if (StringUtils.isNotEmpty(pmUser.getOrgId())) {
            wrapper.eq("org_id", pmUser.getOrgId());
        }
        if (StringUtils.isNotEmpty(pmUser.getUserName())) {
            wrapper.eq("user_name", pmUser.getUserName());
        }
        if (StringUtils.isNotEmpty(pmUser.getPassword())) {
            wrapper.eq("password", pmUser.getPassword());
        }
        if (StringUtils.isNotEmpty(pmUser.getUserState())) {
            wrapper.eq("user_state", pmUser.getUserState());
        }
        if (StringUtils.isNotEmpty(pmUser.getUserType())) {
            wrapper.eq("user_type", pmUser.getUserType());
        }

        if (StringUtils.isNotEmpty(pmUser.getUserSex())) {
            wrapper.eq("user_sex", pmUser.getUserSex());
        }
        if (StringUtils.isNotEmpty(pmUser.getUserPortrait())) {
            wrapper.eq("user_portrait", pmUser.getUserPortrait());
        }
        if (StringUtils.isNotEmpty(pmUser.getUserEmail())) {
            wrapper.eq("user_email", pmUser.getUserEmail());
        }
        if (StringUtils.isNotEmpty(pmUser.getUserWeixin())) {
            wrapper.eq("user_weixin", pmUser.getUserWeixin());
        }
        if (StringUtils.isNotEmpty(pmUser.getUserQq())) {
            wrapper.eq("user_qq", pmUser.getUserQq());
        }
        if (StringUtils.isNotEmpty(pmUser.getUserTel())) {
            wrapper.eq("user_tel", pmUser.getUserTel());
        }
        if (StringUtils.isNotEmpty(pmUser.getPasswordSalt())) {
            wrapper.eq("password_salt", pmUser.getPasswordSalt());
        }
        List<PmUser> list = selectList(wrapper);
        return list;
    }


    /**
     * <pre>校验用户名是否已经存在，如果不存在，则可以注册
     * </pre>
     *
     * @param
     * @return
     * @author test
     * @version 1.0
     * @since 2019/7/24 17:42
     */
   @Override
    public String validateUserName(String userName, String key) {
//        Wrapper<PmUser> wrapper = new EntityWrapper<PmUser>();
//        wrapper.and().eq("user_name", userName);
//        PmUser User = selectOne(wrapper);
//        如果为空，则可以注册
        EntityWrapper wrapper = new EntityWrapper<PmUser>();
        wrapper.eq("user_name", userName);
        String primaryKey = "";
        String validateInfo = super.validateNameRepeatByKey(key, primaryKey, wrapper);
        return validateInfo;
    }

    //验证手机号
    @Override
    public String validateUserTel(String userTel, String key) {
//        Wrapper<PmUser> wrapper = new EntityWrapper<PmUser>();
//        wrapper.and().eq("user_name", userName);
//        PmUser User = selectOne(wrapper);
//        如果为空，则可以注册TestDept
        EntityWrapper wrapper = new EntityWrapper<PmUser>();
        wrapper.eq("user_tel", userTel);
        String primaryKey = "";
        String validateInfo = super.validateNameRepeatByKey(key, primaryKey, wrapper);
        return validateInfo;
    }


    /**
     * <pre>校验邮箱是否已经存在，如果不存在，则可以注册
     * </pre>
     *
     * @param
     * @return
     * @author test
     * @version 1.0
     * @since 2019/7/24 17:42
     */
    @Override
    public boolean validateEmail(String userEmail) {
        Wrapper<PmUser> wrapper = new EntityWrapper<PmUser>();
        wrapper.and().eq("user_email", userEmail);
        PmUser User = selectOne(wrapper);
//        如果为空，则可以注册
        return null == User;
    }


    public PmUser selectOne(Wrapper<PmUser> wrapper) {
        return super.selectOne(wrapper);
    }


    /**
     * 删除的时候同步权限用户表的缓存数据
     *
     * @param id 主键
     * @return
     */
    @Override
    public boolean deleteById(Serializable id) {
        //idMaps接收id
        List<String> userIds = new ArrayList<>();
        userIds.add(id.toString());
        List<Map<String, Object>> idMaps = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        map.put("userId", id.toString());
        idMaps.add(map);
        /**
         * 通过用户id查询用户是否绑定角色
         * 如果用户绑定角色，则提示异常，删除失败
         * 如果用户无绑定角色则提示是否删除
         */
        String ids = (String) id;
        List<PmRole> PmRole = roleService.selectRolesByUserId(null, ids);
        if (PmRole.size() > 0) {
            throw new CgException("此用户绑定角色，删除失败！");
        } else {
            //批量删除人员
            deleteBatchIds(userIds);
            //批量删除人员角色关联信息
            roleService.batchDeleteRoleOnUsers(idMaps);
            return super.deleteById(id);
        }
    }
}